package com.example.server.security;

import com.example.server.mapper.MenuMapper;
import com.example.common.pojo.Admin;
import com.example.common.pojo.Menu;
import com.example.common.pojo.Role;
import com.example.common.vo.RespBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Component
public class DefaultSessionBasedAuthorizeInterceptor implements HandlerInterceptor {

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        /**
         * 1 确定本次请求允许的权限范围
         * 2 收集请求的用户具备的权限范围
         * 3 比较这两者，判断是否有交集
         */

        /**
         * 1 获取url地址
         * 2 获取所有的权限 list menu，每一个权限menu都会同步其对应的role list
         * 3 遍历list menu 将url和menu进行匹配，如果能够找到一个menu，就可以获取这个请求
         * 对应的list role，也就是哪些角色可以访问该地址
         */
        String requestURI = request.getRequestURI();
        // TODO 设置缓存，从缓存中获取该数据
        List<Menu> menus = menuMapper.findAllWithRoles();

        AntPathMatcher antPathMatcher = new AntPathMatcher();

        List<Role> allowedRoles = null;
        for (Menu menu : menus) {

            if (antPathMatcher.match(menu.getUrl(), requestURI)) {

                allowedRoles = menu.getRoles();
            }
        }

        if (allowedRoles == null || allowedRoles.size() == 0) {
            // 如果该资源没有被授权限制，登录之后都可以直接访问
            return true;
        }

        Admin admin = (Admin) request.getSession().getAttribute("auth");
        List<Role> hadRoles = admin.getRoles();

        if (hadRoles != null && hadRoles.size() > 0) {
            // 41x
            for (Role allowedRole : allowedRoles) {

                for (Role hadRole : hadRoles) {

                    if (allowedRole.equals(hadRole)) {
                        return true;
                    }
                }
            }
        }

        throw RespBean.AUTH_FAILED_ERROR_411.toException();
    }
}
